*******************************************************************************
* Custom Window Application
*
* (C)  Copyright Apple Computer, Inc. 1988
* All rights reserved.
*
* by Keith Rollin
* July 7, 1988
*
* This program is not much more than the standard shell that brings up three
* windows. Two of these windows are custom RoundRect windows, and the third
* one is normal window presented for comparison. This program also shows the
* use of _AlertWindow, a call new to System Disk 3.2, and the use of NULL
* events to draw the current time in the menubar.
*
* Files: System macros and equates
*        Custom.Window.inits.aii
*        RoundRect Window.aii
*
*
* Modification History:
*
* Version 1.0       kaar
*
*      July 7, 1988
*
*      First Release
*
*******************************************************************************
*                                                                    *
*             Apple IIGS Source Code Sampler, Volume I               *
*                                                                    *
*             Copyright (c) Apple Computer, Inc. 1988                *
*                       All Rights Reserved                          *
*                                                                    *
*            Written by Apple II Developer Tech Support              *
*                                                                    *
*                                                                    *
*                                                                    *
*  ----------------------------------------------------------------  *
*                                                                    *
*     This program and its derivatives are licensed only for         *
*     use on Apple computers.                                        *
*                                                                    *
*     Works based on this program must contain and                   *
*     conspicuously display this notice.                             *
*                                                                    *
*     This software is provided for your evaluation and to           *
*     assist you in developing software for the Apple IIGS           *
*     computer.                                                      *
*                                                                    *
*     DISCLAIMER OF WARRANTY                                         *
*                                                                    *
*     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT                       *
*     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,               *
*     WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS             *
*     FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO             *
*     THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH            *
*     YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND            *
*     NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)               *
*     ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,             *
*     REPAIR OR CORRECTION.                                          *
*                                                                    *
*     Apple does not warrant that the functions                      *
*     contained in the Software will meet your requirements          *
*     or that the operation of the Software will be                  *
*     uninterrupted or error free or that defects in the             *
*     Software will be corrected.                                    *
*                                                                    *
*     SOME STATES DO NOT ALLOW THE EXCLUSION                         *
*     OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY              *
*     NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC            *
*     LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS                *
*     WHICH VARY FROM STATE TO STATE.                                *
*                                                                    *
*                                                                    *
**********************************************************************



                    mcopy Custwind.macros
                    mcopy New.macros
                    copy 2/ainclude/E16.Quickdraw
                    copy 2/ainclude/E16.Memory
                    copy 2/ainclude/E16.EVENT
                    copy 2/ainclude/E16.Window
                    copy 2/ainclude/E16.Dialog

*******************************************************************************
*
*    Equates used in this program.
*
*******************************************************************************
DPHandle            gequ 0              ; Handle to Tool Direct Page area
DPPointer           gequ DPHandle+4     ; Pointer to Tool Direct Page area
deref               gequ DPPointer+4    ; Temporary Handle dereference area
temp1               gequ deref+4        ; used by DrawTime routine

ScreenMode          gequ Mode640
ScreenWidth         gequ 640

                    EJECT
*******************************************************************************
*
Main                start
*
* Description:      This is the main routine. It calls routines to Initialize
*                   the tools, initialize application specific data, run the
*                   main EventLoop, close the application, and close the tools.
*                   Then it calls the ProDOS Quit command.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import InitTools
*                   Import InitApp
*                   Import EventLoop
*                   Import CloseApp
*                   Import CloseTools
*                   Import QuitParms
*
* Entry Points:     NONE
*
*******************************************************************************
                    using globals
                    jsr InitTools
                    jsr InitApp

                    _ShowCursor

                    jsr EventLoop

                    jsr CloseApp
                    jsr CloseTools

                    _Quit QuitParms

                    end

                    EJECT
*******************************************************************************
*
Globals             data
*
* Description:      Holder of all of our data.
*
*
* Inputs:           N/A
*
* Outputs:          N/A
*
* External Refs:
*
* Entry Points:
*                   Export QuitParms    ; used by Main
*
*******************************************************************************
*
* Standard global data
*
*******************************************************************************

TitleString         str 'Custom Window Sample'
AutString           str 'By Keith Rollin, Apple II DTS'
CopyString          str '(c)1988 Apple Computer'
VerString           str 'Version 1.0           July 7, 1988'
AboutData           dc c'73/*0',i1'13',c'*1',i1'13',c'*2'
                    dc i1'13',c'*3/^#0',i1'0'
SubStrings          dc i4'TitleString,AutString,CopyString,VerString'

MenuHeight          ds 2                ; Stored height of menu bar
MyID                ds 2                ; Application ID
MyDP                ds 2                ; My direct page storage

QuitFlag            ds 2
QuitParms           dc i4'0'            ; Pathname of next app
                    dc i2'$00'          ; flags

EventRecord         ANOP
EventWhat           ds 2
EventMessage        ds 4
EventWhen           ds 4
EventWhere          ds 4
EventModifiers      ds 2
TaskData            ds 4
TaskMask            dc i4'$0000FFFF'

                    EJECT
*******************************************************************************
*
* Application specific global data
*
*******************************************************************************

; This is a list of pointers to the text that is used to create our menus. It
; is used by InitApp to find all of the menu templates and use them to create
; our menubar. This loop loads MenuPtrLen-4 into an index, gets the
; corresponding menu template pointer in this table, and uses that in a
; NewMenu call. It then decrements the index by 4, and repeats the procees
; until the index is negative.

MenuPtr             dc i4'AppMenu'
                    dc i4'FileMenu'
                    dc i4'EditMenu'
MenuPtrLen          equ *-MenuPtr


; Menu list: menu items should be numbered consecutivly starting from 250.
; As a convention, use 256 as about and 257 as Quit.

AppMenu             dc c'$$@\N1',i1'$0D'
                    dc c'--Custom Window...\N256V',i1'$00'
                    dc c'.'
FileMenu            dc c'$$  File  \N2',i1'$0D'
                    dc c'--Open Custom Window 1\N258',i1'$00'
                    dc c'--Open Custom Window 2\N259',i1'$00'
                    dc c'--Open Normal Window\N260',i1'$00'
                    dc c'--Close\N255V',i1'$00'
                    dc c'--Quit\N257*Qq',i1'$00'
                    dc c'.'
EditMenu            dc c'$$  Edit  \N3',i1'$00'
                    dc c'--Undo\N250*ZzVD',i1'$00'
                    dc c'--Cut\N251*XxD',i1'$00'
                    dc c'--Copy\N252*CcD',i1'$00'
                    dc c'--Paste\N253*VvD',i1'$00'
                    dc c'--Clear\N254D',i1'$00'
                    dc c'.'

TestWindow          dc i4'0'
TestWindow2         dc i4'0'
NormalWindow        dc i4'0'

                    end

                    EJECT
*******************************************************************************
*
InitApp             start
*
* Description:      Perform any application specific initialization.
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import RRectDefProc
*                   Import doUpdate
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    stz QuitFlag

                    pha                 ; space for the window pointer
                    pha
                    PushLong #NormWindRec
                    _NewWindow
                    PullLong NormalWindow

                    pha                 ; space for the window pointer
                    pha
                    PushLong #CustWindRec
                    _NewWindow
                    PullLong TestWindow

                    pha                 ; space for the window pointer
                    pha
                    PushLong #CustWindRec2
                    _NewWindow
                    PullLong TestWindow2

                    rts

WindowTitle1        str '  Custom Window #1  '
WindowTitle2        str '  Custom Window #2  '
WindowTitle3        str '  I am a Normal Window  '

myColors            dc i2'$0010' ; Frame color (7-4)
                    dc i2'$02F0' ; Inact ttlbar(11-8), inact ttl(7-4), title (3-0)
                    dc i2'$0005' ; Background color (active titlebar) (3-0)

custWindRec         dc i2'0'
                    dc i4'RRectDefProc'
                    dc i2'0'            ; FrameBits
                    dc i2'40,100,160,500'                   ; bounding rectangle
                    dc i4'$FFFFFFFF'    ; plane
                    dc i4'0'            ; storage
                    dc i4'0'            ; refCon
                    dc i4'doUpdate'     ; contDraw
                    dc i4'WindowTitle1' ; window's title
                    dc i4'myColors'     ; colorTable
                    dc i2'$10'          ; vertical radius
                    dc i2'$20'          ; horizontal radius

custWindRec2        dc i2'0'
                    dc i4'RRectDefProc'
                    dc i2'fClose+fMove'
                    dc i2'60,140,140,440'                   ; bounding rectangle
                    dc i4'$FFFFFFFF'    ; plane
                    dc i4'0'            ; storage
                    dc i4'0'            ; refCon
                    dc i4'doUpdate'     ; contDraw
                    dc i4'WindowTitle2' ; window's title
                    dc i4'0'            ; colorTable
                    dc i2'$10'          ; vertical radius
                    dc i2'$20'          ; horizontal radius

NormWindRec         dc i2'WindEnd-NormWindRec'
                    dc i2'fTitle+fClose+fMove'
                    dc i4'WindowTitle3' ; Ptr to title
                    dc i4'$0'           ; RefCon
                    dc i2'0,0,0,0'      ; Full Size (0= default)
                    dc i4'0'            ; Color Table Pointer
                    dc i2'0,0'          ; Vertical/Horizontal origin
                    dc i2'0,0'          ; Data area height, width
                    dc i2'0,0'          ; Max Cont height, width
                    dc i2'0,0'          ; Pixels to scroll vert'ly, horiz'ly
                    dc i2'0,0'          ; Pixels to page vert'ly, horiz'ly
                    dc i4'0'            ; Information bar refcon.
                    dc i2'0'            ; Info bar height
                    dc i4'0'            ; DefProc.
                    dc i4'0'            ; Routine to draw info. bar.
                    dc i4'doUpdate'     ; Routine to draw content.
                    dc i2'40,40,120,590'                    ; Size and position
                    dc i4'$FFFFFFFF'    ; Plane to put window up in (bottommost).
                    dc i4'0'            ; Address for window record (0 to alloc)
WindEnd             equ *

                    end

                    EJECT
*******************************************************************************
*
CloseApp            start
*
* Description:      Close down things. This disposes of all items and memory
*                   that we allocated.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    PushLong TestWindow
                    _CloseWindow

                    PushLong TestWindow2
                    _CloseWindow

                    PushLong NormalWindow
                    _CloseWindow

                    rts
                    end

                    EJECT
*******************************************************************************
*
EventLoop           start
*
* Description:      Main Event Loop. Handle things until user selects Quit.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:
*                   Import MenuSelect
*                   Import ignore
*                   Import doUpdate
*                   Import doNullEvent
*                   Import doClose
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

maxEvent            equ wInactMenu

                    pha                 ; Push on space for TaskMaster result
                    PushWord #EveryEvent ; GetNextEvent mask
                    PushLong #EventRecord ; Pointer to Event Record
                    _TaskMaster

                    pla                 ; Get TaskMaster result
                    cmp #maxEvent+1     ; do we know this event?
                    blt TaskOK          ; yes - so do it.
                    lda #inNull         ; map unknowns to null events
TaskOK              asl a               ; Turn it into an index
                    tax
                    jsr (TaskTable,x)   ; Call appropriate event handler

                    lda QuitFlag        ; Quit selected?
                    beq EventLoop       ; no - keep looping

                    rts                 ; yes- leave the program

TaskTable           dc i2'doNullEvent'  ; 0 Null
                    dc i2'Ignore'       ; 1 MouseDown
                    dc i2'Ignore'       ; 2 MouseUp
                    dc i2'Ignore'       ; 3 KeyDown
                    dc i2'Ignore'       ; 4 undefined
                    dc i2'Ignore'       ; 5 AutoKey
                    dc i2'Ignore'       ; 6 Update
                    dc i2'Ignore'       ; 7 undefined
                    dc i2'Ignore'       ; 8 Activate
                    dc i2'Ignore'       ; 9 Switch
                    dc i2'Ignore'       ; 10 Desk accessory
                    dc i2'Ignore'       ; 11 Device driver
                    dc i2'Ignore'       ; 12 ap
                    dc i2'Ignore'       ; 13 ap
                    dc i2'Ignore'       ; 14 ap
                    dc i2'Ignore'       ; 15 ap
                    dc i2'Ignore'       ; TASK 0 indesk
                    dc i2'MenuSelect'   ; TASK 1 in menuBar
                    dc i2'Ignore'       ; TASK 2 in system window
                    dc i2'Ignore'       ; TASK 3 in content
                    dc i2'Ignore'       ; TASK 4 in Drag
                    dc i2'Ignore'       ; TASK 5 in grow
                    dc i2'doClose'      ; TASK 6 in goaway
                    dc i2'Ignore'       ; TASK 7 in zoom
                    dc i2'Ignore'       ; TASK 8 in info bar
                    dc i2'MenuSelect'   ; TASK 9 in special menu
                    dc i2'Ignore'       ; TASK 10 in NDA
                    dc i2'Ignore'       ; TASK 11 in frame
                    dc i2'Ignore'       ; TASK 12 in drop

                    end

                    EJECT
*******************************************************************************
*
MenuSelect          start
*
* Description:      This routine is called when TaskMaster returns a menu
*                   event. It takes the menu item that was hit and calculates
*                   an offset into the menu dispatch table. It then calls that
*                   routine and unhilites the menu when it is done.
*
* Inputs:           TaskData holds menu item selected.
*
* Outputs:          NONE
*
* External Refs:
*                   Import ignore
*                   Import doAbout
*                   Import doQuit
*                   Import doOpen1
*                   Import doOpen2
*                   Import doOpen3
*                   Import doClose
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    lda TaskData        ; Get the ID of the menu item selected.
                    sec                 ; Turn it into an index by subtracting
                    sbc #250            ; the starting ID number (250) and mul-
                    asl a               ; tiplying by 2 (each table entry con-
                    tax                 ; sists of 2 bytes).
                    jsr (menuTable,x)   ; Call the routine behind it.

                    PushWord #0         ; Routine done - unhilite the menubar.
                    PushWord taskData+2
                    _HiLiteMenu

                    rts

MenuTable           dc i2'Ignore'       ; undo
                    dc i2'Ignore'       ; cut
                    dc i2'Ignore'       ; copy
                    dc i2'Ignore'       ; paste
                    dc i2'Ignore'       ; clear
                    dc i2'DoClose'      ; close
                    dc i2'DoAbout'      ; about this program
                    dc i2'DoQuit'       ; quit selected
                    dc i2'DoOpen1'      ; open a custom window
                    dc i2'DoOpen2'      ; open another custom window
                    dc i2'DoOpen3'      ; open a normal window
                    end

                    EJECT
*******************************************************************************
*
Ignore              start
*
* Description:      Called when I want to ignore an event.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************

                    rts
                    end

                    EJECT
*******************************************************************************
*
DoNullEvent         start
*
* Description:      Performs tasks when there is nothing else to do...In this
*                   case, draw the time in the menubar.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; get the time
                    pha
                    pha
                    pha
                    _ReadTimeHex

                    lda 1,s             ; compare to see if 1 second
                    cmp oldTime         ; has passed...
                    bne DrawTime

                    lda 3,s
                    cmp oldTime+2
                    bne DrawTime

                    lda 5,s
                    cmp oldTime+4
                    bne DrawTime

                    lda 7,s
                    cmp oldTime+6
                    bne DrawTime
                    brl ExitNull        ; no it hasn't...do nothing

DrawTime            ANOP                ; time has passed, draw it.
                    pha                 ; save the old port
                    pha
                    _GetPort
                    PullLong oldPort

                    pha                 ; switch to the menu manager port
                    pha
                    _GetMenuMgrPort
                    lda 1,s             ; save this for metrics later
                    sta temp1
                    lda 3,s
                    sta temp1+2
                    _SetPort

                    PushLong #TimeString ; get the time as a string
                    _ReadAsciiTime

                    ldx #18             ; strip off the high bits
loop                lda TimeString,x
                    and #$7F7F
                    sta TimeString,x
                    dex
                    dex
                    bpl Loop

                    pha                 ; get the length of the time string
                    PushLong #TimeString
                    _CStringWidth

; put it on the screen so that its right edge is 10 pixels from
; the right edge of the screen. It is always positioned 10 pixels
; down from the top of the screen.

                    ldy #oportRect+6
                    lda [temp1],y
                    sec
                    sbc 1,s             ; subtract the width on the stack
                    sbc #10             ; plus some...
                    sta 1,s             ; push on the X-Coord
                    ldy #oportRect
                    lda [temp1],y
                    clc
                    adc #10             ; push on the Y-coord
                    pha
                    _MoveTo

; Save and set the text mode to modeCopy
                    pha
                    _GetTextMode

                    PushWord #0
                    _SetTextMode

; Finally draw the string

                    PushLong #TimeString
                    _DrawCString

; Reset the text mode and the GrafPort

                    _SetTextMode

                    PushLong oldPort
                    _SetPort

ExitNull            ANOP
                    PullLong oldTime
                    PullLong oldTime+4

                    rts

oldTime             dc i1'0,0,0,0,0,0,0,0'
oldPort             ds 4

TimeString          ds 20
                    dc i1'0'

                    end

                    EJECT
*******************************************************************************
*
doUpdate            start
*
* Description:      Called by TaskMaster to perform updates. This routine
*                   does nothing, as we have nothing to update with!
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    rtl
                    end

                    EJECT
*******************************************************************************
*
doQuit              start
*
* Description:      Quit routine. Set the QuitFlag to TRUE for the EventLoop.
*
*
* Inputs:           NONE
*
* Outputs:          QuitFlag set to $FFFF
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    lda #$FFFF
                    sta QuitFlag
                    rts
                    end


                    EJECT
*******************************************************************************
*
doAbout             start
*
* Description:      Bring up an AlertWindow box with our name in it. This call
*                   was added on System Disk 3.2.
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using Globals

                    pha                 ; space for result
                    PushWord #1         ; we are using P-Strings
                    PushLong #SubStrings
                    PushLong #AboutData
                    _AlertWindow        ; new macro defined above
                    pla                 ; pull off button hit

                    rts

                    end

                    EJECT
*******************************************************************************
*
doOpen              start
*
* Description:      Opens a window by making it visible.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:
*                   entry doOpen1
*                   entry doOpen2
*                   entry doOpen3
*
*******************************************************************************
                    using Globals
                    
doOpen1             entry
                    lda TestWindow
                    ldx TestWindow+2
                    bra CommonOpen

doOpen2             entry
                    lda TestWindow2
                    ldx TestWindow2+2
                    bra CommonOpen

doOpen3             entry
                    lda NormalWindow
                    ldx NormalWindow+2

CommonOpen          ANOP
                    phx                 ; push the window ptr on for ShowWind
                    pha
                    phx                 ; and push a set on for Select
                    pha
                    _SelectWindow       ; bring it to front
                    _ShowWindow         ; and show it.

                    rts

                    end


                    EJECT
*******************************************************************************
*
doClose             start
*
* Description:      Closes a window by making it invisible.
*
*
* Inputs:           NONE
*
* Outputs:          NONE
*
* External Refs:    NONE
*
* Entry Points:     NONE
*
*******************************************************************************
                    using globals

                    pha                 ; get the front window
                    pha
                    _FrontWindow
                    _HideWindow         ; and hide it

                    rts
                    end

                    copy cw.inits.src
                    copy DefProc.1.src
                    copy DefProc.2.src

                    END
